package com.rerun.service.impl;

import com.rerun.common.sms.SmsTemplate;
import com.rerun.common.sms.SmsUtil;
import com.rerun.common.util.Validator;
import com.rerun.entity.MessageRecords;
import com.rerun.enums.MessageRecordsEnum;
import com.rerun.enums.RedisKeySuffixEnum;
import com.rerun.service.IMessageRecordsService;
import com.rerun.service.ISmsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.concurrent.TimeUnit;


/**
 * @author dax.
 * @version v1.0
 * @since 2017/11/1 10:39
 */
@Service
public class SmsServiceImpl implements ISmsService {
    private static final Logger log = LoggerFactory.getLogger("SMS");
    private static final String SUCCESS_CODE = "000000";

    @Resource
    private IMessageRecordsService iMessageRecordsService;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;


    @Override
    public boolean sendCaptcha(String phoneNumber) {

        boolean isPhone = Validator.isMobile(phoneNumber);
        if (isPhone) {
            String code = SmsUtil.getRandomNum(5);
            SmsTemplate smsTemplate = SmsTemplate.setConfirmCode(phoneNumber, code);
            String resultCode = SmsUtil.sendSms(smsTemplate);

            MessageRecords record = new MessageRecords();
            record.setReceivePhone(smsTemplate.getPhone());
            record.setSendContent(Arrays.toString(smsTemplate.getData()));
            record.setValidity(Long.valueOf(smsTemplate.getData()[1]) * 60 * 1000);
            record.setSendTime(new Date());
            record.setCreateTime(new Date());
            record.setTemplateCode(smsTemplate.getId());
            record.setStatusCode(resultCode);
            log.debug("to: {} resultCode: {}", phoneNumber, resultCode);

            boolean flag = SUCCESS_CODE.equals(resultCode);
            if (flag) {
                record.setSendStatus(MessageRecordsEnum.SUCCESS.getKey());
                ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
                valueOperations.set(phoneNumber + RedisKeySuffixEnum.SMS_CODE_CACHE_KEY_SUFFIX.getKey(), code, 300, TimeUnit.SECONDS);
            } else {
                record.setSendStatus(MessageRecordsEnum.FAILURE.getKey());
            }
            iMessageRecordsService.insert(record);
            return flag;
        }
        return false;
    }

    @Override
    public boolean sendSms(SmsTemplate smsTemplate) {
        String resultCode = SmsUtil.sendSms(smsTemplate);

        MessageRecords record = new MessageRecords();
        record.setReceivePhone(smsTemplate.getPhone());
        record.setSendContent(Arrays.toString(smsTemplate.getData()));
        record.setStatusCode(resultCode);
        record.setValidity(Long.valueOf(smsTemplate.getData()[1]) * 60 * 1000);
        record.setSendTime(new Date());
        record.setCreateTime(new Date());
        record.setTemplateCode(smsTemplate.getId());

        log.debug("to: {} resultCode: {}", smsTemplate.getPhone(), resultCode);

        boolean flag = SUCCESS_CODE.equals(resultCode);
        if (flag) {
            record.setSendStatus(MessageRecordsEnum.SUCCESS.getKey());
        } else {
            record.setSendStatus(MessageRecordsEnum.FAILURE.getKey());
        }
        iMessageRecordsService.insert(record);
        return flag;
    }

    @Override
    public boolean verifySmsCode(String phoneNumber, String smsCode) {
        String key = phoneNumber + RedisKeySuffixEnum.SMS_CODE_CACHE_KEY_SUFFIX.getKey();
        if (redisTemplate.hasKey(key)) {
            ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
            String codeCacheVal = (String) valueOperations.get(key);
            boolean flag = smsCode.equals(codeCacheVal);
            if (flag) {
                redisTemplate.delete(key);
            }
            return flag;
        }
        return false;
    }
}
